#include "CircularBuffer.h"


// 初始化缓冲区（对应C++构造函数）
void CircularBuffer_Init(CircularBuffer* cb) {
    cb->bufferEnd = cb->buffer + CIRCULAR_BUFFER_SIZE - 1;
    cb->writeP = cb->buffer;
    cb->readP = cb->buffer;
}

// 清空缓冲区
void CircularBuffer_Clear(CircularBuffer* cb) {
    cb->writeP = cb->buffer;
    cb->readP = cb->buffer;
}


size_t CircularBuffer_Size(const CircularBuffer* cb) {
    return (cb->writeP - cb->readP + CIRCULAR_BUFFER_SIZE) % CIRCULAR_BUFFER_SIZE)
}


size_t CircularBuffer_Capacity(const CircularBuffer* cb) {
    return CIRCULAR_BUFFER_SIZE - 1;// 最大容量（总空间 - 1，因为不能完全填满）
}


bool CircularBuffer_Empty(const CircularBuffer* cb) {
    return cb->writeP == cb->readP;
}


uint8_t* CircularBuffer_Begin(const CircularBuffer* cb) {
    if (CircularBuffer_Empty(cb)) return NULL;
    return cb->readP;
}


uint8_t* CircularBuffer_End(const CircularBuffer* cb) {
    if (CircularBuffer_Empty(cb)) return NULL;
    size_t tailIndex = (cb->readP + CircularBuffer_Size(cb) - 1 - cb->buffer + CIRCULAR_BUFFER_SIZE) % (CIRCULAR_BUFFER_SIZE);
    return (cb->buffer + tailIndex);
}


bool CircularBuffer_Append(CircularBuffer* cb, const uint8_t* data, size_t length) {
    if (length == 0) return true;
    if (length > (CircularBuffer_Capacity(cb) - CircularBuffer_Size(cb))) return false;

    if (cb->writeP + length <= cb->bufferEnd) {
        memcpy(cb->writeP, data, length);
        cb->writeP += length;
    }
    else {
        size_t endLength = cb->bufferEnd - cb->writeP + 1;
        size_t beginLength = length - endLength;
        memcpy(cb->writeP, data, endLength);
        memcpy(cb->buffer, data + endLength, beginLength);
        cb->writeP = cb->buffer + beginLength;
    }
    return true;
}


bool CircularBuffer_Consume(CircularBuffer* cb, uint8_t* rBuffer, size_t length) {
    if (length == 0) return true;
    if (length > CircularBuffer_Size(cb)) return false;

    if (cb->readP + length <= cb->bufferEnd) {
        memcpy(rBuffer, cb->readP, length);
        cb->readP += length;
    }
    else {
        size_t endLength = cb->bufferEnd - cb->readP + 1;
        size_t beginLength = length - endLength;
        memcpy(rBuffer, cb->readP, endLength);
        memcpy(rBuffer + endLength, cb->buffer, beginLength);
        cb->readP = cb->buffer + beginLength;
    }
    return true;
}


bool CircularBuffer_EraseFront(CircularBuffer* cb, uint8_t* it) {
    if (CircularBuffer_Empty(cb)) return false;
    if (it < cb->buffer || it > cb->bufferEnd) return false;

    size_t itMapIndex = (it - cb->readP) % (CIRCULAR_BUFFER_SIZE);//指针以数据头为开头的索引
    size_t tailMapIndex = CircularBuffer_Size(cb) - 1;//数据尾部，以数据头为开头的索引
    if (itMapIndex > tailMapIndex) return false;//目标不在数据区内，错误

    cb->readP = it;
    return true;
}


uint8_t* CircularBuffer_Find(CircularBuffer* cb, const uint8_t* target, size_t length) {
    if (target == NULL) return NULL;
    if (length == 0) return CircularBuffer_Begin(cb);
    if (length > CircularBuffer_Size(cb)) return NULL;
    
    //虚拟数组中“最后一次比较的后一个”的索引
    size_t lastBehindMapIndex = CircularBuffer_Size(cb) - length + 1 + 1;
    //真实数组中“最后一次比较的后一个”的索引
    size_t lastBehindIndex = (cb->readP - cb->buffer + lastBehindMapIndex) % CIRCULAR_BUFFER_SIZE;
    //真实数组中“最后一次比较的后一个”的位置。
    uint8_t* lastBehind = cb->buffer + lastBehindIndex;
    uint8_t* it = cb->readP;

    while (it != lastBehind) {
        if (it + length <= cb->bufferEnd) {
            if (memcmp(it, target, length) == 0) {
                return it;
            }
        }
        else {
            size_t endLength = cb->bufferEnd - it + 1;
            size_t beginLength = length - endLength;
            if (memcmp(it, target, endLength) == 0 && memcmp(cb->buffer, target + endLength, beginLength) == 0) {
                return it;
            }
        }
        it++;
        if (it > cb->bufferEnd) it = cb->buffer;//超过范围，回到开头
    }
    return NULL;
}

